package fr.utbm.tx52.stamp.adapter;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import fr.utbm.tx52.stamp.R;
import fr.utbm.tx52.stamp.logic.Contact;
import fr.utbm.tx52.stamp.logic.DataManager;
import fr.utbm.tx52.stamp.ui.activity.Main;
import fr.utbm.tx52.stamp.ui.fragment.ContactItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Un adaptateur pour afficher la liste des contacts dans une listActivity
 *
 * @author Xavier MICHEL (xavier.michel@utbm.fr) David LACHICHE
 * (david.lachiche@utbm.fr)
 */
public class ContactsAdapter extends BaseAdapter
{

	/**
	 * Le context de l'adapter
	 */
	private Activity mContext;
	/**
	 * Le calque de l'adapter
	 */
	private LayoutInflater mInflater;
	/**
	 * La liste des contacts avec lequels on remplit l'adapter
	 */
	private List<Contact> contacts = new ArrayList<Contact>();
	private String filter;
	private Map<Integer, Integer> filtered;
	private List<Contact> selected = new ArrayList<Contact>();

	public List<Contact> getSelected()
	{
		return selected;
	}

	public final void setContacts(List<Contact> contacts)
	{
		int i = this.contacts.size();
		this.contacts.addAll(contacts);
		for (; i < this.contacts.size(); ++i)
		{
			fragments.add(i, new ContactItem(mContext));
			fragments.get(i).setContact(this.contacts.get(i));
		}
		setFilter(filter);
	}

	public final void setMe(Contact me)
	{
		if (listener == Listener.REMOVE)
		{
			if (!contacts.isEmpty())
			{
				contacts.remove(0);
				fragments.remove(0);
			}
			this.me = me;
			contacts.add(0, me);
			ContactItem item = new ContactItem(mContext);
			fragments.add(0, item);
			item.setContact(me);
			setFilter(filter);
		}
	}

	public void addContact(Contact contact)
	{
		contacts.add(contact);
		ContactItem item = new ContactItem(mContext);
		fragments.add(item);
		item.setContact(contact);
		setFilter(filter);
	}

	public void removeContact(Contact contact)
	{
		contacts.remove(contact);
		for (ContactItem item : fragments)
		{
			if (item.getContact() == contact)
			{
				fragments.remove(item);
				break;
			}
		}
		setFilter(filter);
	}
	private List<ContactItem> fragments = new ArrayList<ContactItem>();
	private Contact me;
	private Listener listener;

	/**
	 * Construit l'adapter
	 *
	 * @param c Le context pour lequel on cr�� l'adapter
	 * @param contacts La liste des contacts qui vont peupler la liste
	 */
	public ContactsAdapter(Activity activity, List<Contact> contacts, Listener mode)
	{
		mContext = activity;
		listener = mode;
		mInflater = LayoutInflater.from(mContext);
		SharedPreferences preferences = mContext.getPreferences(Activity.MODE_PRIVATE);
		String myPhone = preferences.getString(Main.PREFERENCE_ME_KEY, "");
		if ((DataManager.getMyPhoneNumber(activity) == null || "".equals(DataManager.getMyPhoneNumber(activity))) && "".equals(myPhone))
		{
			setMe(null);
		}
		else
		{
			setMe(Contact.getContactsByPhone(mContext, "".equals(myPhone) ? DataManager.getMyPhoneNumber(activity) : myPhone));
		}
		setContacts(contacts);
	}

	/**
	 * Compte le nombre de contacts dans la liste
	 *
	 * @return Le nombre de contacts dans la liste
	 */
	public int getCount()
	{
		return filtered.size();
	}

	/**
	 * Renvoi le contact � la position donn�e
	 *
	 * @param position La position dont on veut le contact
	 *
	 * @return Le contact � la position donn�e
	 */
	public Object getItem(int position)
	{
		return filtered.get(position);
	}

	/**
	 * Identifie une ligne
	 *
	 * @return Renvoi l'identifiant d'une ligne
	 */
	public long getItemId(int position)
	{
		return position;
	}

	/**
	 * Rempli une ligne de la liste des contacts
	 */
	public View getView(int position, View convertView, ViewGroup parent)
	{

		final Contact contact = contacts.get(filtered.get(position));
		final fr.utbm.tx52.stamp.ui.fragment.ContactItem fragment = fragments.get(filtered.get(position));
		fragment.onCreateView(mInflater, parent, Bundle.EMPTY);
		fragment.setContact(contact);
		fragment.drawContact();

		if (selected.contains(contact))
		{
			fragment.getLinearLayout().setBackgroundColor(Color.parseColor("#0099CC"));
		}
		else
		{
			fragment.getLinearLayout().setBackgroundColor(0);
		}

		if (contact != null && contact != me)
		{
			listener.contact = contact;
			listener.contactsAdapter = this;
			fragment.getLinearLayout().setOnClickListener(listener);
		}
		else if (contact == me)
		{
			fragment.getLinearLayout().setBackgroundColor(Color.parseColor("#FAFAFA"));
		}
		return fragment.getLinearLayout();
	}

	public void setFilter(String newText)
	{
		this.filter = newText;
		this.filtered = new HashMap<Integer, Integer>();
		for (Contact contact : contacts)
		{
			if (contact == null)
			{
				filtered.put(filtered.size(), contacts.indexOf(contact));
				continue;
			}
			if (contact.matchFilter(filter))
			{
				filtered.put(filtered.size(), contacts.indexOf(contact));
			}
		}
		notifyDataSetChanged();
	}

	public enum Listener implements View.OnClickListener
	{

		REMOVE,
		SELECT;
		public ContactsAdapter contactsAdapter;
		private Contact contact;

		public void onRemoveClick(View v)
		{
			DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
			{

				@Override
				public void onClick(DialogInterface dialog, int which)
				{
					switch (which)
					{
						case DialogInterface.BUTTON_POSITIVE:
							DataManager.removeAssociatedContacts(contactsAdapter.mContext, contact);
							contactsAdapter.removeContact(contact);
							break;

						case DialogInterface.BUTTON_NEGATIVE:
							//No button clicked
							break;
					}
				}
			};

			AlertDialog.Builder builder = new AlertDialog.Builder(contactsAdapter.mContext);
			builder.setMessage("Voulez-vous supprimer \"" + contact.getName() + "\" ?").setPositiveButton("Oui", dialogClickListener).setNegativeButton("Non", dialogClickListener).show();
		}

		public void onSelectClick(View v)
		{
			if (contactsAdapter.selected.contains(contact))
			{
				v.setBackgroundColor(0);
				contactsAdapter.selected.remove(contact);
			}
			else
			{
				v.setBackgroundColor(Color.parseColor("#0099CC"));
				contactsAdapter.selected.add(contact);
			}
			contactsAdapter.notifyDataSetChanged();
		}

		public void onClick(View v)
		{
			String phone =
				"" + ((TextView) ((LinearLayout) v).findViewById(R.id.contact_phone)).getText();
			for (Contact contact : contactsAdapter.contacts)
			{
				if (contact.getPhoneNumber().equals(phone))
				{
					this.contact = contact;
					break;
				}
			}

			switch (this)
			{
				case REMOVE:
					onRemoveClick(v);
					break;
				case SELECT:
					onSelectClick(v);
					break;
			}
		}
	}
}
